home *** CD-ROM | disk | FTP | other *** search
/ PC World Interactive 7 / PC World Interactive 7.iso / program / cprog.EXE / OBJ2ASM.ZIP / OMAIN.C < prev    next >
Text File  |  1991-10-02  |  18KB  |  453 lines

  1. /*
  2. ** OBJASM - Utility to create .ASM files out of .OBJ files.
  3. **          Options are:
  4. **
  5. **              -r = Create RASM86 compatible output (.A86 instead of .ASM)
  6. **              -4 = Make compatible with MASM v4.0 (no retf)
  7. **              -a = Add labels for un-named data references
  8. **              -h = Hex output as comments
  9. **              -v = 486 instructions
  10. **             -s# = Minimum string size in data segment
  11. **             -c# = Minimum string size in code segment
  12. **    -f(filename) = Additional information filename (w/paren.)
  13. **
  14. **    Includes 8086/80186/80286/80386/80486
  15. **    and 8087/80287/80387 coprocessor instructions
  16. **    See OBJASM.DOC for a more detailed description.
  17. **    (C) Copyright 1988,1989,1990,1991 by Robert F. Day, All rights reserved.
  18. **
  19. **          Send/phone questions, comments, and bugs to:
  20. **
  21. **              Robert F. Day
  22. **              19906 Filbert Dr.
  23. **              Bothell, WA 98012
  24. **              (206) 481-8431
  25. */
  26.  
  27. #include <stdio.h>
  28. #include <stdlib.h>
  29. #include <string.h>
  30. #include <alloc.h>
  31. #include "o.h"
  32.  
  33.                                     /*--- Expanded INTEL OMF record types --*/
  34. #define RHEADR  0x6E                /*   R-Module Header Record             */
  35. #define REGINT  0x70                /*   Register Initialization Record     */
  36. #define REDATA  0x72                /*   Relocatable Enumerated Data Record */
  37. #define RIDATA  0x74                /*   Relocatable Iterated Data Record   */
  38. #define OVLDEF  0x76                /*   Overlay Definition Record          */
  39. #define ENDREC  0x78                /*   End Record                         */
  40. #define BLKREC  0x7A                /*   Block Definition Record            */
  41. #define BKLEND  0x7C                /*   Block End Record                   */
  42. #define DEBSYM  0x7E                /*   Debug Symbols Record               */
  43. #define THEADR  0x80                /* x T-Module Header Record             */
  44. #define LHEADR  0x82                /*   L-Module Header Record             */
  45. #define PEDATA  0x84                /*   Physical Enumerated Data (?)       */
  46. #define PIDATA  0x86                /*   Physical Iterated Data (?)         */
  47. #define COMENT  0x88                /* x Comment Record                     */
  48. #define MODEND  0x8A                /* x Module End Record                  */
  49. #define MODENDL 0x8B                /* l Module End Record                  */
  50. #define EXTDEF  0x8C                /* x External Names Definition Record   */
  51. #define TYPDEF  0x8E                /*   Type Definitions Record            */
  52. #define PUBDEF  0x90                /* x Public Names Definition Record     */
  53. #define PUBDEFL 0x91                /* l Public Names Definition Record     */
  54. #define LOCSYM  0x92                /*   Local Symbols Record               */
  55. #define LINNUM  0x94                /*   Line Numbers Record                */
  56. #define LNAMES  0x96                /* x List of Names Record               */
  57. #define SEGDEF  0x98                /* x Segment Definition Record          */
  58. #define SEGDEFL 0x99                /* l Segment Definition Record          */
  59. #define GRPDEF  0x9A                /* x Group Definition Record            */
  60. #define FIXUPP  0x9C                /* x Fix-Up Record                      */
  61. #define FIXUPPL 0x9D                /* l Fix-Up Record                      */
  62. #define LEDATA  0xA0                /* x Logical Enumerated Data            */
  63. #define LEDATAL 0xA1                /* l Logical Enumerated Data            */
  64. #define LIDATA  0xA2                /* x Logical Iterated Data              */
  65. #define LIDATAL 0xA3                /* l Logical Iterated Data              */
  66. #define LIBHED  0xA4                /*   Library Header Record              */
  67. #define LIBNAM  0xA6                /*   Library Module Names Record        */
  68. #define LIBLOC  0xA8                /*   Library Module Locations Record    */
  69. #define LIBDIC  0xAA                /*   Library Dictionary Record          */
  70. #define COMDEF  0xB0                /* m Communal Data Definition Record    */
  71. #define LEXTDEF 0xB4                /* m Local External Definition          */
  72. #define LPUBDEF 0xB6                /* m Local Public Definition            */
  73. #define LPUBDF2 0xB7                /* m Local Public Definition (2nd case?)*/
  74. #define LCOMDEF 0xB8                /* m Local Communal Data Definition     */
  75. #define LIBHDR  0xF0                /* m Library Header Record              */
  76. #define LIBEND  0xF1                /* m Library Trailer Record             */
  77.                                     /* x = Intel OMF used by Microsoft      */
  78.                                     /* m = Microsoft Additions to Intel OMF */
  79.                                     /* l = Later extensions by Microsoft    */
  80. /*
  81. ** Local Prototypes
  82. */
  83. int main( int, char *[] );
  84.  
  85. FILE    *o_file;                    /* .OBJ file that we are processing */
  86. long    o_position;                 /* Position in file of current data */
  87.  
  88. NODE_T  *line_tree;
  89. NODE_T  *arg_scope_tree;
  90. NODE_T  *loc_scope_tree;
  91. NODE_T  *end_scope_tree;
  92.  
  93. NODE_T  *name_tree;
  94. NODE_T  *segment_tree;
  95. NODE_T  *group_tree;
  96. NODE_T  *public_tree;
  97. NODE_T  *extern_tree;
  98. NODE_T  *sex_tree;
  99. NODE_T  *data_tree;
  100. NODE_T  *struc_tree;
  101. NODE_T  *fix_tree;
  102. NODE_T  *hint_tree;
  103. NODE_T  *type_tree;
  104. NODE_T  *block_tree;
  105.  
  106. SEG_T   *seg_rec;
  107. SEG_T   seg_search;
  108. GRP_T   grp_search;
  109.  
  110. NODE_T  *pub_node;
  111. PUB_T   *pub_rec;
  112. PUB_T   *last_pub_rec;
  113. PUB_T   pub_search;
  114.  
  115. NODE_T  *hint_node;
  116. HINT_T  *hint_rec;
  117. HINT_T  hint_search;
  118.  
  119. THREAD_T threads[2][4] = {0};
  120.  
  121. NODE_T  *fix_node;
  122. FIX_T   *fix_rec;
  123. FIX_T   fix_search;
  124.  
  125. NAME_T  name_search;
  126.  
  127. int      label_count = 0;
  128.  
  129. int             segment;
  130. dword   inst_offset;
  131. int             processor_mode = 0;
  132. int             segment_mode;
  133. int             segment_bytes;
  134.  
  135. char            *cseg_name;
  136. PUB_T           *start_pub = NULL;
  137.  
  138. word    code_string = 40;   /* Stringizing Limit in Code */
  139. word    data_string =  3;   /* Stringizing Limit in Data */
  140.  
  141. int     pass;                       /* 1=Building Labels, 2=Generating Output */
  142. int     processor_type_comment_occurred = FALSE;    /* No processor spec yet */
  143.  
  144. int     hex_finish;                 /* For hex comments */
  145.  
  146. int     tab_offset = 0;             /* Current tab offset, 0 = none */
  147.  
  148. int     compatibility = 0;          /* 0 = MASM 5.0+ (Microsoft) */
  149.                                     /* 1 = MASM 4.0  (Microsoft) */
  150.                                     /* 2 = RASM86 (Digital Research) */
  151.  
  152. int     add_labels = FALSE;         /* No, treat as .obj translator       */
  153.                                     /* Otherwise, treat as .asm creator   */  
  154.                                     /* Translator is a strict translation */
  155.  
  156. int     hex_output = FALSE;         /* Display hex code as comments? */
  157.  
  158. char    extra_filename[65] = {'\0'};/* Additional information file */
  159.  
  160. /*
  161. ** ------- Exit values -------- **
  162. ** 0 = Successful operation     **
  163. ** 1 = Improper Usage           **
  164. ** 2 = Unable to open OBJ file  **
  165. ** 3 = Premature end of file    **
  166. ** 4 = Out of memory            **
  167. ** 5 = .OBJ Format error        **
  168. ** 6 = Unable to open ADD file  **
  169. ** 7 = Syntax error in ADD file **
  170. ** ------- Exit values -------- **
  171. */
  172.  
  173.  
  174.  
  175. int main( argc, argv )
  176.     int     argc;
  177.     char    *argv[];
  178. {
  179.     char            *argp;
  180.     int             name_arg;
  181.     int             argi;
  182.     int             bad_args;
  183.     char            *fnamep;
  184.     dword   position;
  185.     int             at_eof;
  186.     int             rec_type;
  187.     word    rec_length;
  188.     char            temp_name[50];
  189.     char            ch;
  190.     int             i486;
  191.  
  192.     bad_args = FALSE;
  193.     argi = 1;
  194.     name_arg = 0;
  195.     i486 = FALSE;
  196.     while ( argi < argc ) {
  197.         argp = argv[argi];
  198.         if ( *argp++ == '-' ) {
  199.             while ( *argp ) {
  200.                 switch ( *argp ) {
  201.                     case 'a':
  202.                         add_labels = TRUE;
  203.                         break;
  204.                     case '4':
  205.                         compatibility = 1;
  206.                         break;
  207.                     case 'r':
  208.                         compatibility = 2;
  209.                         break;
  210.                     case 'h':
  211.                         hex_output = TRUE;
  212.                         break;
  213.                     case 'v':
  214.                         i486 = TRUE;
  215.                         break;
  216.                     case 'c':
  217.                         code_string = atoi(argp+1);
  218.                         while ( (ch = *(argp+1)) != '\0' ) {
  219.                             if ( ch < '0' || ch > '9' ) {
  220.                                 break;
  221.                             }
  222.                             argp++;
  223.                         }
  224.                         break;
  225.                     case 's':
  226.                         code_string = atoi(argp+1);
  227.                         while ( (ch = *(argp+1)) != '\0' ) {
  228.                             if ( ch < '0' || ch > '9' ) {
  229.                                 break;
  230.                             }
  231.                             argp++;
  232.                         }
  233.                         break;
  234.                     case 'f':
  235.                         argp++;
  236.                         if ( *argp != '(' ) {
  237.                             bad_args = TRUE;
  238.                             break;
  239.                         }
  240.                         fnamep = extra_filename;
  241.                         while ( (ch = *(argp+1)) != '\0' ) {
  242.                             argp++;
  243.                             if ( ch == ')' ) {
  244.                                 *fnamep = '\0';
  245.                                 break;
  246.                             }
  247.                             *fnamep++ = ch;
  248.                         }
  249.                         if ( ch == '\0' ) {
  250.                             bad_args = TRUE;
  251.                         }
  252.                         break;
  253.                     default:
  254.                         bad_args = TRUE;
  255.                         break;
  256.                 }
  257.                 argp++;
  258.             }
  259.         } else {
  260.             if ( name_arg == 0 ) {
  261.                 name_arg = argi;
  262.             } else {
  263.                 bad_args = TRUE;
  264.             }
  265.         }
  266.         argi++;
  267.     }
  268.  
  269.     if ( name_arg == 0 ) {
  270.         bad_args = TRUE;
  271.     }
  272.  
  273.     if ( bad_args ) {
  274.         fprintf( stderr, "Usage:  %s [-options] [objfilename]\n", argv[0] );
  275.         fprintf( stderr, "where -options are:\n" );
  276.         fprintf( stderr, "           -4 Make MASM 4.0 compatible (no RETF)\n" );
  277.         fprintf( stderr, "           -a Add labels for un-named data references\n");
  278.         fprintf( stderr, "           -h Hex output in comments\n");
  279.         fprintf( stderr, "           -r Make RASM86 compatible\n" );
  280.         fprintf( stderr, "           -v Include 486 instructions\n" );
  281.         fprintf( stderr, "          -c# Minimum string size in a code segment (default=40)\n");
  282.         fprintf( stderr, "          -s# Mimimum string size in a data segment (default=3)\n");
  283.         fprintf( stderr, " -f(filename) Additional information filename (w/paren.)\n");
  284.         fprintf( stderr, "\n" );
  285.         fprintf( stderr, "Additional information file lines:\n");
  286.         fprintf( stderr, "SEG sname CODE                named segment is a code segment\n");
  287.         fprintf( stderr, "SEG sname DATA                named segment is a data segment\n");
  288.         fprintf( stderr, "var=sname:####                creates a local label in segment name\n");
  289.         fprintf( stderr, "sname:####:DB/DW/DD/DF/DQ/DT  directs dis-assembly into data\n");
  290.         fprintf( stderr, "... (for more info, read OBJASM.DOC)\n");
  291.         exit(1);
  292.     }
  293.  
  294.     switch( compatibility ) {
  295.         case 0:             /* MASM 5.0+ */
  296.             if ( i486 ) {
  297.                 ex_instr[0x08].text = "invd";
  298.                 ex_instr[0x09].text = "wbinvd";
  299.                 op_grp[6][7] = "invlpg";
  300.                 ex_instr[0xA6].text = "cmpxchg";
  301.                 ex_instr[0xA7].text = "cmpxchg";
  302.                 ex_instr[0xC0].text = "xadd";
  303.                 ex_instr[0xC1].text = "xadd";
  304.                 ex_instr[0xC8].text = "bswap";
  305.                 ex_instr[0xC9].text = "bswap";
  306.                 ex_instr[0xCA].text = "bswap";
  307.                 ex_instr[0xCB].text = "bswap";
  308.                 ex_instr[0xCC].text = "bswap";
  309.                 ex_instr[0xCD].text = "bswap";
  310.                 ex_instr[0xCE].text = "bswap";
  311.                 ex_instr[0xCF].text = "bswap";
  312.  
  313.             }
  314.             break;
  315.         case 1:             /* MASM 4.0  */
  316.             /*
  317.             ** Make far return only a comment
  318.             */
  319.             instr[0xCB].text = "ret\t; (retf)";
  320.             break;
  321.         case 2:             /* RASM86 */
  322.             /*
  323.             ** Make xlat a xlat bx
  324.             */
  325.             instr[0xD7].text = "xlat\tbx";
  326.             /*
  327.             ** Make short jmp a jmps
  328.             */
  329.             instr[0xEB].text = "jmps";
  330.             /*
  331.             ** Make far jmp a jmpf
  332.             */
  333.             op_grp[4][5] = "jmpf";
  334.             break;
  335.     }
  336.  
  337.     strcpy( temp_name, argv[name_arg] );
  338.     if ( strchr(temp_name,'.') == NULL ) {  /* Append ".obj" if no extension */
  339.         strcat( temp_name, ".obj" );        /* is supplied                   */
  340.     }
  341.  
  342.     o_file = fopen( temp_name, "rb" );
  343.     if ( o_file == NULL ) {
  344.         fprintf( stderr, "%s: Cannot open %s\n", argv[0], temp_name );
  345.         exit(2);
  346.     }
  347.  
  348.     /* Print copyright message */
  349.     printf("; OBJASM version 2.0 released on Jan 3, 1991\n");
  350.     printf("; (C) Copyright 1988,1989,1990,1991 by Robert F. Day.  All rights reserved\n\n");
  351.  
  352.     init_trees();                   /* Initialize all trees */
  353.  
  354.     at_eof = FALSE;
  355.     position = 0;
  356.  
  357.     while ( !at_eof ) {
  358.         fseek( o_file, position, L_SET );
  359.  
  360.         rec_type = fgetc( o_file );
  361.  
  362.         if ( rec_type == EOF ) {
  363.             at_eof = TRUE;
  364.         } else {
  365.             rec_length = getw( o_file );
  366.  
  367.             o_position = position + 3;      /* (1 rec_type) + (2 rec_length) */
  368.  
  369. #ifdef DEBUG
  370.             printf("PROCESSING rec_type [%02X] rec_length [%04X]\n",
  371.                                                     rec_type, rec_length );
  372. #endif
  373.  
  374.             switch( rec_type ) {
  375.               case THEADR:  theadr();                       break;
  376.               case LNAMES:  lnames( rec_length );           break;
  377.               case GRPDEF:  grpdef( rec_length );           break;
  378.               case SEGDEF:  segdef();                       break;
  379.               case SEGDEFL: segdef();                       break;
  380.               case PUBDEF:  pubdef( rec_length, TRUE );     break;
  381.               case PUBDEFL: pubdef( rec_length, TRUE );     break;
  382.               case LPUBDEF: pubdef( rec_length, FALSE );    break;
  383.               case LPUBDF2: pubdef( rec_length, FALSE );    break;
  384.               case EXTDEF:  extdef( rec_length, TRUE );     break;
  385.               case LEXTDEF: extdef( rec_length, FALSE );    break;
  386.               case LEDATA:  ledata( rec_length, REGULAR );  break;
  387.               case LEDATAL: ledata( rec_length, LARGER );   break;
  388.               case LIDATA:  lidata( rec_length, REGULAR );  break;
  389.               case LIDATAL: lidata( rec_length, LARGER );   break;
  390.               case FIXUPP:  fixupp( rec_length, REGULAR );  break;
  391.               case FIXUPPL: fixupp( rec_length, LARGER );   break;
  392.               case COMDEF:  comdef( rec_length, TRUE );     break;
  393.               case LCOMDEF: comdef( rec_length, FALSE );    break;
  394.               case MODEND:  modend( rec_length, REGULAR );
  395.                             at_eof = TRUE;                  break;
  396.               case MODENDL: modend( rec_length, LARGER );
  397.                             at_eof = TRUE;                  break;
  398.               case TYPDEF:                                  break;
  399.               case COMENT:  printf("; [%04X]",position);
  400.                             coment( rec_length );           break;
  401.               case LINNUM:  linnum( rec_length );           break;
  402.               default:  printf( "Bad record type: [%08lX:%02X:%04X]\n",
  403.                                 position, rec_type, rec_length          );
  404.                         break;
  405.             }
  406.             position += 3 + rec_length;
  407.         }
  408.     }
  409.  
  410. #ifdef DEBUG
  411.     printf("PROCESSING dis-assembly, pass 1\n");
  412. #endif
  413.  
  414.     if ( strlen(extra_filename) != 0 ) {
  415.         load_extra( argv[0], extra_filename );
  416.     }
  417.  
  418.     pass = 1;
  419.     process();                      /* First pass: Processing */
  420.  
  421.     pass = 2;
  422.     process();                      /* Second pass: Figure out labels */
  423.  
  424. #ifdef DEBUG
  425.     printf("PROCESSING listing externals\n");
  426. #endif
  427.  
  428.     list_ext();                     /* Show EXTERNAL's */
  429.  
  430. #ifdef DEBUG
  431.     printf("PROCESSING listing publics and communal definitions\n");
  432. #endif
  433.  
  434.     list_pub();                     /* Show PUBLIC's */
  435.  
  436.     list_struc();                   /* Show STRUC's */
  437.  
  438. #ifdef DEBUG
  439.     printf("PROCESSING dis-assembly, pass 2 (last)\n");
  440. #endif
  441.  
  442.     pass = 3;
  443.     process();                      /* Third pass: Output */
  444.  
  445.     fclose( o_file );
  446.  
  447. #ifdef DEBUG
  448.     printf("END OF RUN\n");
  449. #endif
  450.  
  451.     return(0);
  452. }
  453.